﻿using Autofac;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WebSocketCore.Domain.Account;

namespace WebSocketCore.Domain.Entities
{
    public class ChatRoomEntity : INotify
    {
        public WebSocket this[IUser user]
        {
            get
            {
                if (webSockets.Any(m => m.User.Id == user.Id))
                {
                    return webSockets.First(m => m.User.Id == user.Id).WebSocket;
                }
                return null;
            }
            set
            {
                if (webSockets.Any(m => m.User.Id == user.Id))
                {
                    var ws = webSockets.First(m => m.User.Id == user.Id);
                    ws.WebSocket = value;
                }
                else
                {
                    WebSocketEntity entity = new WebSocketEntity() { User = user, WebSocket = value };
                    webSockets.Add(entity);
                }

            }
        }
        protected IList<WebSocketEntity> webSockets = new List<WebSocketEntity>();
        public string Id { get; set; }
        public string ChatRoomName { get; set; }
        public int UserCount
        {
            get { return webSockets.Count; }
        }
        protected IMessageManager messageManager = Cfg.Ioc.Resove<IMessageManager>();
        public async Task AddUser(IUser user, WebSocket webSocket)
        {
           
            this[user] = webSocket;
            await NotifyAsync(messageManager.UserLogIn(user.Name, ChatRoomName));
            while (webSocket.State == WebSocketState.Open)
            {
                byte[] buffer = new byte[1024 * 4];
                WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
                if (result.MessageType == WebSocketMessageType.Close)
                {
                    await RemoveUser(user, webSocket);
                    await NotifyAsync(messageManager.UserLogOut(user.Name));
                }
                else
                {
                    string userMsg = Encoding.UTF8.GetString(buffer, 0, result.Count);
                    MessageEntity msg = messageManager.CreateMsg(user.Name, userMsg);
                    await NotifyAsync(msg);
                }
            }
        }
        public bool HasUser(IUser user)
        {
            return webSockets.Any(m => m.User.Id == user.Id);
        }
        public async Task RemoveUser(IUser user,WebSocket webSocket,bool dispose=true)
        {
            webSockets.Remove(webSockets.First(m => m.User.Id== user.Id));
            if (dispose)
            {
                await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "服务端关闭", CancellationToken.None);
            }
            await NotifyAsync(messageManager.UserLogOut(user.Name));
        }
        public IList<WebSocketEntity> WebSockets
        {
            get { return webSockets; }
        }
        public async Task NotifyAsync(MessageEntity msg)
        {
            foreach (var item in webSockets)
            {
                await item.NotifyAsync(msg);
            }
        }
    }
}
